package Dic;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 * 说明:将Unicode汉字编码转换成UTF-8编码形式,然后根据UTF-8编码方式构造汉字字符
 * @author liujun_lu
 */
public class UTF8 {

	/**
	 * @param args
	 * @throws UnsupportedEncodingException
	 */
	public final static String UTF8_HIGHT_BIT3_STYLE = "1110XXXX";
	public final static String UTF8_LOW_BIT_STYLE = "10XXXXXX";
	public final static int MIN_CODEPOINT = 0X4E00;
	public final static int MAX_CODEPOINT = 0X9FA5;

	public static void main(String[] args) throws UnsupportedEncodingException {
		byte[] utf8Bytes = new byte[3];
		for (int codePoint = MIN_CODEPOINT; codePoint <= MAX_CODEPOINT; codePoint++) {
			String binaryStr = Integer.toBinaryString(codePoint);
			int length = binaryStr.length();
			/**汉字Unicode编码值二进制数形式为15位或16位*/
			if (!(15 == length || 16 == length)) {
				throw new IllegalArgumentException(
						"Unicode Chinese characters coding errors");
			}
			/**
			 * Unicode采用双字节编码,如果编码值所对应的二进制不满16位,在高位补0
			 */
			if (15 == length) {
				binaryStr = String.valueOf('0') + binaryStr;
			}
			/**
			 * 将汉字Unicode编码值转换成UTF-8编码形式
			 */
			String part1 = binaryStr.substring(0, 4);
			String part2 = binaryStr.substring(4, 10);
			String part3 = binaryStr.substring(10);
			String bit1Str = UTF8_HIGHT_BIT3_STYLE.replaceFirst("[xX]+", part1);
			String bit2Str = UTF8_LOW_BIT_STYLE.replaceFirst("[xX]+", part2);
			String bit3Str = UTF8_LOW_BIT_STYLE.replaceFirst("[xX]+", part3);
			utf8Bytes[0] = binary8ToInt(bit1Str);
			utf8Bytes[1] = binary8ToInt(bit2Str);
			utf8Bytes[2] = binary8ToInt(bit3Str);
			System.out.println(new String(utf8Bytes, "UTF-8"));
		}

	}

	public static List getUTF8Cn() throws Exception{
		List cnList=new ArrayList<String>();
		byte[] utf8Bytes = new byte[3];
		for (int codePoint = MIN_CODEPOINT; codePoint <= MAX_CODEPOINT; codePoint++) {
			String binaryStr = Integer.toBinaryString(codePoint);
			int length = binaryStr.length();
			/**汉字Unicode编码值二进制数形式为15位或16位*/
			if (!(15 == length || 16 == length)) {
				throw new IllegalArgumentException(
						"Unicode Chinese characters coding errors");
			}
			/**
			 * Unicode采用双字节编码,如果编码值所对应的二进制不满16位,在高位补0
			 */
			if (15 == length) {
				binaryStr = String.valueOf('0') + binaryStr;
			}
			/**
			 * 将汉字Unicode编码值转换成UTF-8编码形式
			 */
			String part1 = binaryStr.substring(0, 4);
			String part2 = binaryStr.substring(4, 10);
			String part3 = binaryStr.substring(10);
			String bit1Str = UTF8_HIGHT_BIT3_STYLE.replaceFirst("[xX]+", part1);
			String bit2Str = UTF8_LOW_BIT_STYLE.replaceFirst("[xX]+", part2);
			String bit3Str = UTF8_LOW_BIT_STYLE.replaceFirst("[xX]+", part3);
			utf8Bytes[0] = binary8ToInt(bit1Str);
			utf8Bytes[1] = binary8ToInt(bit2Str);
			utf8Bytes[2] = binary8ToInt(bit3Str);
			cnList.add(new String(utf8Bytes, "UTF-8"));
		}
		return cnList;
	};
	/**
	 * 将8位二进制整数(字符串形式)转化十进制整数(byte)
	 * 
	 * @param binary8Str
	 * @return int
	 */
	private static byte binary8ToInt(String binary8Str) {
		Pattern p = Pattern.compile("[0-1]{8}");
		Matcher m = p.matcher(binary8Str);
		if (!m.matches()) {
			throw new IllegalArgumentException("Error 8 bit binary integer");
		}
		/**
		 * 根据最高位判断是正数(0)还是负数(1)
		 */
		int sign = Integer.parseInt(Character.toString(binary8Str.charAt(0)));
		/**求反码 */
		String revCode;
		if (1 == sign) {
			/** 等于1表示负数 */
			StringBuffer revCodeBuf = new StringBuffer();
			revCodeBuf.append(0);
			for (int index = 1; index < 8; index++) {
				if (49 == binary8Str.codePointAt(index)) {
					revCodeBuf.append(0);
				} else {
					revCodeBuf.append(1);
				}
			}
			revCode = revCodeBuf.toString();
		} else {
			revCode = binary8Str;
		}
		byte result = 0;
		for (int bit = 7; bit > 0; bit--) {
			if (49 == revCode.codePointAt(8 - bit)) {
				result += Math.pow(2, bit - 1);
			} else {
				continue;
			}
		}
		/**
		 * 求负数原码值
		 */
		if (1 == sign) {
			result = (byte) (-(result + 1));
		}
		return result;
	}
}
